/**
 * Touch Event
 *
 * provide tap sweepLeft sweepRight sweepTop sweepDown 
 */
;(function(win){
	var CustomEvent = function(type, config) {
		var e = document.createEvent('CustomEvent');
		e.initCustomEvent(type, config.bubbles, config.cancelable, config.detail);
		return e;
	};
	var NOW = function(){
		return +(new Date);
	};
	var getPageX = function(e){
		return e.pageX || e.touches[0].pageX;
	};
	var getPageY = function(e){
		return e.pageY || e.touches[0].pageY;
	}
	var target, startX, startY, pageX, pageY, offsetX, offsetY, startTime, onTouchStart, onTouchMove, onTouchEnd, onTouchCancel, config;
	config = {
		tapThreshold: {
			move: 5,
			time: 300
		},
		sweepThreshold: {
			move: 5
		}

	};
	onTouchStart = function(e) {
		startTime = NOW();
		startX = pageX = getPageX(e);
		startY = pageY = getPageY(e);
		target = e.target;
	}

	onTouchMove = function(e) {
		pageX = getPageX(e);
		pageY = getPageY(e);
	}

	onTouchCancel = onTouchEnd = function(e) {
		var timelapse, absOffsetX, absOffsetY, maxOffset, isTap, isSweep, isSweepLeft, isSweepRight, isSweepUp, isSweepDown, eventType;
		timelapse = NOW() - startTime;
		offsetX = pageX - startX;
		offsetY = pageY - startY;
		absOffsetX = Math.abs(offsetX);
		absOffsetY = Math.abs(offsetY);
		maxOffset = Math.max(absOffsetX, absOffsetY);
		//console.log(timelapse,offsetX, offsetY, maxOffset)
		if(timelapse <= config.tapThreshold.time && maxOffset <= config.tapThreshold.move){
			isTap = true;
			eventType = 'tap';
		}else{
			if(maxOffset > config.sweepThreshold.move){
				isSweep = true;
				if(absOffsetX > absOffsetY){
					if(offsetX > 0){
						isSweepRight = true;
						eventType = 'sweepright';
					}else{
						isSweepLeft = true;
						eventType = 'sweepleft';
					}
				}else{
					if(offsetY > 0){
						isSweepDown = true;
						eventType = 'sweepdown';
					}else{
						isSweepUp = true;
						eventType = 'sweepup';
					}
				}
				
			}
		}
		/*
		var info = 'elapse time: ' + timelapse + '<br>offset x: ' + offsetX + '<br>offset y: ' + offsetY + '<br>max offset: ' + maxOffset + '<br>is tap: ' + isTap + '<br>is sweep: ' + isSweep + '<br>is sweep left: ' + isSweepLeft + '<br>is sweep right: ' + isSweepRight + '<br>is sweep up: ' + isSweepUp + '<br>is sweep down: ' + isSweepDown;
		console.log(info.replace(/\<br\>/g, '\n'));
		*/
		if(eventType && target){
			var customEvent = new CustomEvent(eventType, {
				bubbles: true,
				cancelable: true
			});
			//console.log(target, customEvent)
			target.dispatchEvent(customEvent);
		}
	}

	var addEvent = function(element, type, fn){
		if(!element)
			return
		if(win.attachEvent){
			element.attachEvent("on" + type, fn);
		}else{
			element.addEventListener(type, fn, false);
		}
	};
	if('ontouchstart' in win) {
		window.addEventListener('touchstart', onTouchStart);
		window.addEventListener('touchmove', onTouchMove);
		window.addEventListener('touchend', onTouchEnd);
	}
	else {
		addEvent(win, 'click', function(e){
			var event = e || window.event;
			var ele = event.target;
			if(ele){
				var customEvent = new CustomEvent('tap', {bubbles: true, cancelable: true});
				ele.dispatchEvent(customEvent);
			}
		});
	}
	if('ontouchcancel' in win) {
		window.addEventListener('touchcancel', onTouchCancel);
	}
})(window);
